//////////////////////////////////////////////////////////////////////////////////////////////////
// 
// File: texQuad.cpp
// 
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Renders a textured quad.  Demonstrates creating a texture, setting
//       texture filters, enabling a texture, and texture coordinates.
//          
//////////////////////////////////////////////////////////////////////////////////////////////////

#include<vld.h>
#include "d3dUtility.h"
#include <time.h>
#include <TCHAR.H>
#include "Vertex.h"
#include "Move.h"
#include <vector>
using namespace std;

//
// Globals
//

IDirect3DDevice9*     Device = 0; 

const int Width  = 1024;
const int Height = 768;
 
IDirect3DVertexBuffer9* Quad = 0;
IDirect3DTexture9*      Tex  = 0;
IDirect3DVertexBuffer9* Curve = 0;



vector<POINT> CurvePoint;
IDirect3DVertexBuffer9* CurveBuffer = 0;

Vertex* v;

const int MAX_NUM = 15;
Parabola g_Parabola[MAX_NUM];
Move g_Move;


void RecordVertex()
{

	Device->CreateVertexBuffer(6*sizeof(Vertex), 
							   D3DUSAGE_WRITEONLY,
							   Vertex::FVF,
							   D3DPOOL_MANAGED,
							   &Curve,
							   0);

	Curve->Lock(0, 0, (void**)&v, 0);

	v[0] = Vertex(0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
	v[1] = Vertex(-10.0f,  10.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
	v[2] = Vertex( 10.0f,  10.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

	v[3] = Vertex(-10.0f, -10.0f, 10.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
	v[4] = Vertex( 10.0f,  10.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
	v[5] = Vertex( 10.0f, -10.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);

	Curve->Unlock();
}
void RecordPoint()
{
	Device->CreateVertexBuffer(CurvePoint.size()*sizeof(Vertex),
							   D3DUSAGE_WRITEONLY,
							   Vertex::FVF,
							   D3DPOOL_MANAGED,
							   &CurveBuffer,
							   0);
	Vertex * t_V;
	CurveBuffer->Lock(0, 0, (void**)&t_V, 0);
	int i = 0; 
	while(i < CurvePoint.size())
	{
		v[i] = Vertex(CurvePoint[i].x,CurvePoint[i].y,0.0f);
		++i;
	}
	CurveBuffer->Unlock();
}
void DrawLight()
{

}

bool Setup()
{
	Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
	Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

	Device->CreateVertexBuffer(
		6 * sizeof(Vertex), 
		D3DUSAGE_WRITEONLY,
		Vertex::FVF,
		D3DPOOL_MANAGED,
		&Quad,
		0);

	Vertex* v;
	Quad->Lock(0, 0, (void**)&v, 0);

	// quad built from two triangles, note texture coordinates:
	v[0] = Vertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
	v[1] = Vertex(-1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
	v[2] = Vertex( 1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

// 	v[3] = Vertex(-1.0f, -1.0f, 10.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
// 	v[4] = Vertex( 1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
	v[5] = Vertex( 1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);

	Quad->Unlock();

	//RecordVertex();
	D3DXCreateTextureFromFile(
		Device,
		"cratewalpha2.dds",//"alpha.bmp",//"ButtonInToolBarBG2.bmp",//"dx5_logo.bmp",
		&Tex);

	Device->SetTexture(0, Tex);

	Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
	
// 	Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
//  Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
	Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
	Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
	//
	Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	// Don't use lighting for this sample.
	//
	Device->SetRenderState(D3DRS_LIGHTING, false);

	//
	// Set the projection matrix.
	//
	D3DXVECTOR3 position(0.0f, 0.0f, -40.0f);
	D3DXVECTOR3 target(0.0f, 0.0f, 1.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
	D3DXMATRIX V;
	D3DXMatrixLookAtLH(&V, &position, &target, &up);
	Device->SetTransform(D3DTS_VIEW, &V);

	Device->SetRenderState(D3DRS_LIGHTING, false);

	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI*0.5f, 16/9/*(float)Width/(float)Height*/, 1.0f, 1000.0f);
	//D3DXMatrixOrthoRH(&proj, D3DX_PI*0.5f, 16/9/*(float)Width/(float)Height*/, 1.0f, 10.0f);
	Device->SetTransform(D3DTS_PROJECTION, &proj);
	return true;
}

void Cleanup()
{
	d3d::Release<IDirect3DVertexBuffer9*>(Quad);
	d3d::Release<IDirect3DTexture9*>(Tex);
	d3d::Release<IDirect3DVertexBuffer9*>(Curve);
}

bool Display(float timeDelta)
{
	if( Device )
	{
		//RecordPoint();
		Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x004f4f4f/*0xffffffff*//*0x00000000*/, 1.0f, 0);
		Device->BeginScene();

		Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

		//Device->Draw
		int i = 0;
		while(i < MAX_NUM)//-1)//
		{
			g_Move.InitSource(g_Parabola[i]);
#ifdef _DEBUG
			if(true)
			{
				TCHAR t_szMess[200];
				_stprintf(t_szMess,TEXT("x:%f\t y:%f\n"),g_Parabola[i].xDest, g_Parabola[i].yDest);
				OutputDebugString(t_szMess);
			}
#endif
			Device->SetTexture(0, Tex);

			D3DXMATRIX Rz;
			D3DXMatrixRotationZ(&Rz, g_Parabola[i].zRotation); 
			D3DXMATRIX translation;
			D3DXMatrixTranslation(&translation, g_Parabola[i].xDest,g_Parabola[i].yDest,0);
			g_Move.CalculateTranslation(g_Parabola[i], timeDelta);
			D3DXMATRIX matrix;
			matrix = Rz*translation;
			Device->SetTransform(D3DTS_WORLD, &matrix);
			Device->SetStreamSource(0, Quad, 0, sizeof(Vertex));
			Device->SetFVF(Vertex::FVF);
			Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
			++i;
 		}
#ifdef _DEBUG
		TCHAR t_szMess[200];
		_stprintf(t_szMess,TEXT("\n"));
		OutputDebugString(t_szMess);
#endif

		Device->SetTexture(0,0);
		//Device->SetStreamSource(0,Curve,0, sizeof(Vertex));
		Device->SetStreamSource(0,CurveBuffer,0, sizeof(Vertex));
		Device->SetFVF(Vertex::FVF);
		Device->DrawPrimitive(D3DPT_LINESTRIP,0,6); 


		Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

		Device->EndScene();
		Device->Present(0, 0, 0, 0);
	}
	return true;
}


bool lButtonDown =  false;
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch( msg )
	{
	case WM_CREATE:
		srand ((unsigned)time(NULL));
		break;
	case WM_LBUTTONDOWN:
		lButtonDown = true;
		break;
	case WM_LBUTTONUP:
		lButtonDown = false;
		break;
	case WM_MOUSEMOVE:
		{
			if(lButtonDown)
			{
				POINT t_Point;
				t_Point.x = LOWORD(lParam);
				t_Point.y = HIWORD(lParam); 
				CurvePoint.push_back(t_Point);
			}
		}
		break;
	case WM_DESTROY:
		::PostQuitMessage(0);
		break;
		
	case WM_KEYDOWN:
		if( wParam == VK_ESCAPE )
			::DestroyWindow(hwnd);
		break;
	}
	return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
				   HINSTANCE prevInstance, 
				   PSTR cmdLine,
				   int showCmd)
{
	if(!d3d::InitD3D(hinstance,
		Width, Height, true, D3DDEVTYPE_HAL, &Device))
	{
		::MessageBox(0, "InitD3D() - FAILED", 0, 0);
		return 0;
	}
	if(!Setup())
	{
		::MessageBox(0, "Setup() - FAILED", 0, 0);
		return 0;
	}

	d3d::EnterMsgLoop( Display );

	Cleanup();

	Device->Release();

	return 0;
}